package com.xhwl.logistics.converter.mapstruct;

import com.xhwl.common.exception.BusinessException;
import com.xhwl.logistics.bo.VehicleCarChargeBO;
import com.xhwl.logistics.bo.VehicleCarChargeInfoBO;
import com.xhwl.logistics.bo.input.QueryVehicleCarChargeBO;
import com.xhwl.logistics.dto.http.query.QueryCarChargeKeTopDTO;
import com.xhwl.logistics.dto.query.VehicleCarChargeDTO;
import com.xhwl.logistics.enums.VehicleCardTypeEnum;
import com.xhwl.logistics.enums.VehicleTimeRangeEnum;
import com.xhwl.logistics.util.AboutDateUtil;
import com.xhwl.logistics.vo.VehicleCarChargeInfoVO;
import com.xhwl.logistics.vo.VehicleCarChargeVO;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.NullValueMappingStrategy;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface VehicleCarChargeConverter {

    //************Query BO <- Controller DTO************
    default QueryVehicleCarChargeBO vehicleCarChargeDTO2QueryVehicleCarChargeBO(VehicleCarChargeDTO vehicleCarChargeDTO) {
        QueryVehicleCarChargeBO queryVehicleCarChargeBO = new QueryVehicleCarChargeBO();
        queryVehicleCarChargeBO.setProjectId(vehicleCarChargeDTO.getProjectId());
        queryVehicleCarChargeBO.setParkingLotName(vehicleCarChargeDTO.getParkingLotName());

        String startTime = vehicleCarChargeDTO.getStartTime();
        String endTime = vehicleCarChargeDTO.getEndTime();
        String timeRange = vehicleCarChargeDTO.getTimeRange();
        if (StringUtils.isNoneEmpty(startTime, endTime)) {
            queryVehicleCarChargeBO.setStartTime(startTime);
            queryVehicleCarChargeBO.setEndTime(endTime);
        } else if (StringUtils.isNotEmpty(timeRange)) {
            VehicleTimeRangeEnum vehicleTimeRangeEnum = VehicleTimeRangeEnum.toVehicleTimeRangeEnum(timeRange);
            switch (vehicleTimeRangeEnum) {
                case TODAY:
                    throw new BusinessException("目前不支持当天的查询");
                case YESTERDAY:
                    throw new BusinessException("目前不支持昨天的查询");
                case THIS_MONTH:
                    Date now = new Date();
                    queryVehicleCarChargeBO.setStartTime(AboutDateUtil.dateToString(AboutDateUtil.theSameMonthOfDate(now)));
                    queryVehicleCarChargeBO.setEndTime(AboutDateUtil.dateToString(now));
                    break;
                default:
                    throw new BusinessException("目前不支持其他的时间范围查询");
            }
        } else {
            throw new BusinessException("输入的查询条件出错，要么输入startTime和endTime，要么输入timeRange");
        }

        return queryVehicleCarChargeBO;
    }
    //************Query BO <- Controller DTO************



    //************Query Http DTO <- Query BO************
    //************Ke Top************
    default QueryCarChargeKeTopDTO queryVehicleCarChargeBO2QueryCarChargeKeTopDTO(QueryVehicleCarChargeBO queryVehicleCarChargeBO) {
        QueryCarChargeKeTopDTO queryCarChargeKeTopDTO = new QueryCarChargeKeTopDTO();
        queryCarChargeKeTopDTO.setBeginTime(queryVehicleCarChargeBO.getStartTime());
        queryCarChargeKeTopDTO.setEndTime(queryVehicleCarChargeBO.getEndTime());
        return queryCarChargeKeTopDTO;
    }
    //************Ke Top************
    //************Query Http DTO <- Query BO************



    //************VO <- BO************
    default VehicleCarChargeVO vehicleCarChargeBO2VehicleCarChargeVO(VehicleCarChargeBO vehicleCarChargeBO) {
        VehicleCarChargeVO vehicleCarChargeVO = new VehicleCarChargeVO();

        vehicleCarChargeVO.setParkingLotName(vehicleCarChargeBO.getParkingLotName());

        Map<String, Integer> mapForTemp = vehicleCarChargeBO.getList().stream()
                .collect(Collectors.toMap(VehicleCarChargeInfoBO::getCardType, VehicleCarChargeInfoBO::getPay));

        List<VehicleCarChargeInfoVO> vehicleCarChargeInfoVOList = Stream.of(VehicleCardTypeEnum.validVehicleCardTypeEnum())
                .map(vehicleCardTypeEnum -> new VehicleCarChargeInfoVO(vehicleCardTypeEnum.getCode()))
                .collect(Collectors.toList());
        vehicleCarChargeInfoVOList.forEach(vehicleCarChargeInfoVO -> {
            Optional.ofNullable(mapForTemp.get(vehicleCarChargeInfoVO.getCardType()))
                    .ifPresent(vehicleCarChargeInfoVO::setPay);
        });

        int totalPay = vehicleCarChargeInfoVOList.stream().mapToInt(VehicleCarChargeInfoVO::getPay).sum();

        vehicleCarChargeVO.setTotalPay(totalPay);
        vehicleCarChargeVO.setList(vehicleCarChargeInfoVOList);
        return vehicleCarChargeVO;
    }
    //************VO <- BO************

}
